﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Timers;
using RxjhServer.HelperTools;
using RxjhServer.Network;

namespace RxjhServer
{
    public class Connect
    {
        private System.Timers.Timer 自动连接;

        private Socket listenSocket;

        private byte[] dataReceive;

        public Connect()
        {
            dataReceive = new byte[1500];
            自动连接 = new System.Timers.Timer(5000.0);
            自动连接.Elapsed += 自动连接事件;
            自动连接.AutoReset = true;
            自动连接.Enabled = true;
        }

        private void 自动连接事件(object source, ElapsedEventArgs e)
        {
            if (World.jlMsg == 1)
            {
                Form1.WriteLine(0, "自动连接事件");
            }
            if (!listenSocket.Connected)
            {
                Sestup();
            }
        }

        public void Sestup()
        {
            try
            {
                IPAddress address = IPAddress.Parse(World.帐号验证服务器IP);
                IPEndPoint remoteEP = new IPEndPoint(address, World.帐号验证服务器端口);
                listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                listenSocket.BeginConnect(remoteEP, ConnectCallback, listenSocket);
            }
            catch (Exception ex)
            {
                Form1.WriteLine(2, "连接帐号验证服务器出错 " + World.帐号验证服务器端口 + " IP " + World.帐号验证服务器IP.ToString() + " " + ex.Message);
            }
        }

        public void Dispose()
        {
            if (自动连接 != null)
            {
                自动连接.Enabled = false;
                自动连接.Close();
                自动连接.Dispose();
            }
            try
            {
                listenSocket.Shutdown(SocketShutdown.Both);
            }
            catch
            {
            }
            if (listenSocket != null)
            {
                listenSocket.Close();
            }
            listenSocket = null;
        }

        public void 复查用户登陆()
        {
            try
            {
                StringBuilder stringBuilder = new StringBuilder();
                foreach (NetState value in World.list.Values)
                {
                    stringBuilder.Append(value.Player.Userid);
                    stringBuilder.Append("-");
                    stringBuilder.Append(value.Player.Client.绑定帐号);
                    stringBuilder.Append("-");
                    stringBuilder.Append(value.Player.Client.ToString());
                    stringBuilder.Append("-");
                    stringBuilder.Append(value.Player.人物全服ID.ToString());
                    stringBuilder.Append("-");
                    stringBuilder.Append(value.Player.UserName);
                    if (value.Player.是否人物离线挂机)
                    {
                        stringBuilder.Append("-1");
                    }
                    stringBuilder.Append(",");
                }
                if (stringBuilder.Length > 0)
                {
                    stringBuilder.Remove(stringBuilder.Length - 1, 1);
                }
                World.conn.发送("复查用户登陆|" + stringBuilder);
            }
            catch (Exception ex)
            {
                Form1.WriteLine(1, "复查用户登陆 错误" + ex.Message);
            }
        }

        private void ConnectCallback(IAsyncResult ar)
        {
            try
            {
                Socket socket = (Socket)ar.AsyncState;
                socket.EndConnect(ar);
                try
                {
                    发送("服务器连接登陆|" + World.服务器ID + "|" + World.最大在线 + "|" + CRC32.GetEXECRC32());
                    Form1.WriteLine(2, "帐号服务器连接成功 端口 " + World.帐号验证服务器端口 + " IP " + World.帐号验证服务器IP);
                    listenSocket.BeginReceive(dataReceive, 0, dataReceive.Length, SocketFlags.None, OnReceiveData, this);
                    Thread.Sleep(500);
                    发送("更新服务器端口|" + World.服务器ID + "|" + World.游戏服务器端口2);
                    复查用户登陆();
                }
                catch (Exception ex)
                {
                    Form1.WriteLine(1, "验证服务器ConnectCallback出错：" + ex.Message);
                }
            }
            catch (Exception ex2)
            {
                Form1.WriteLine(1, "帐号服务器连接出错：" + ex2.Message);
            }
        }

        public virtual void OnReceiveData(IAsyncResult ar)
        {
            try
            {
                int num = listenSocket.EndReceive(ar);
                if (num > 0)
                {
                    ProcessDataReceived(dataReceive, num);
                    listenSocket.BeginReceive(dataReceive, 0, dataReceive.Length, SocketFlags.None, OnReceiveData, this);
                }
            }
            catch (Exception ex)
            {
                Form1.WriteLine(1, "帐号服务器 接收出错：" + ex.Message);
            }
        }

        public void 发送(string msg)
        {
            try
            {
                if (listenSocket != null && listenSocket.Connected)
                {
                    byte[] bytes = Encoding.Default.GetBytes(msg);
                    Send(bytes, bytes.Length);
                }
            }
            catch (Exception ex)
            {
                Form1.WriteLine(1, "验证服务器发送出错：" + msg + ex.Message);
            }
        }

        public virtual void Send(byte[] toSendBuff, int len)
        {
            try
            {
                byte[] array = new byte[len + 6];
                array[0] = 170;
                array[1] = 102;
                Buffer.BlockCopy(BitConverter.GetBytes(len), 0, array, 2, 4);
                Buffer.BlockCopy(toSendBuff, 0, array, 6, len);
                listenSocket.BeginSend(array, 0, len + 6, SocketFlags.None, OnSended2, this);
            }
            catch (SocketException ex)
            {
                Form1.WriteLine(1, "帐号服务器 发送出错：" + ex.Message);
            }
            catch (Exception ex2)
            {
                Form1.WriteLine(1, "帐号服务器 发送出错：" + ex2.Message);
            }
        }

        public void OnSended2(IAsyncResult ar)
        {
            try
            {
                listenSocket.EndSend(ar);
            }
            catch (Exception ex)
            {
                Form1.WriteLine(1, "帐号服务器 发送出错：" + ex.Message);
            }
        }

        public void ProcessDataReceived(byte[] data, int length)
        {
            try
            {
                int num = 0;
                if (170 == data[0] && 102 == data[1])
                {
                    byte[] array = new byte[4];
                    Buffer.BlockCopy(data, 2, array, 0, 4);
                    int num2 = BitConverter.ToInt32(array, 0);
                    if (length >= num2 + 6)
                    {
                        while (true)
                        {
                            if (World.jlMsg == 1)
                            {
                                Form1.WriteLine(0, "ProcessDataReceived");
                            }
                            byte[] array2 = new byte[num2];
                            Buffer.BlockCopy(data, num + 6, array2, 0, num2);
                            num += num2 + 6;
                            DataReceived(array2, num2);
                            if (num >= length || data[num] != 170 || data[num + 1] != 102)
                            {
                                break;
                            }
                            Buffer.BlockCopy(data, num + 2, array, 0, 4);
                            num2 = BitConverter.ToInt16(array, 0);
                        }
                    }
                }
                else
                {
                    Form1.WriteLine(1, "错包3：" + data[0] + " " + data[1]);
                }
            }
            catch (Exception ex)
            {
                Form1.WriteLine(1, "出错：" + ex.Message);
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.Source);
                Console.WriteLine(ex.StackTrace);
            }
        }

        public void DataReceived(byte[] data, int length)
        {
            string @string = Encoding.Default.GetString(data);
            try
            {
                string[] array = @string.Split('|');
                switch (array[0])
                {
                    case "用户登陆":
                        用户登陆(int.Parse(array[2]), array[1], array[3], array[4], array[5], array[6]);
                        break;
                    case "用户换线登陆":
                        用户换线登陆(int.Parse(array[4]), array[1], array[2], array[3], array[4], array[6], array[7], array[8]);
                        break;
                    case "用户踢出":
                        if (array[1].Length != 0)
                        {
                            用户踢出(int.Parse(array[1]), array[2]);
                        }
                        break;
                    case "用户踢出ID":
                        if (array[1].Length != 0)
                        {
                            用户踢出ID(array[1]);
                        }
                        break;
                    case "发送公告":
                        发送公告(int.Parse(array[1]), array[2]);
                        break;
                    case "全服公告":
                        World.全局提示(array[2], int.Parse(array[1]), array[3]);
                        break;
                    case "势力战掉线":
                        if (World.势力战掉线玩家 != null && !World.势力战掉线玩家.ContainsKey(array[1]))
                        {
                            World.势力战掉线玩家.Add(array[1], array[2]);
                        }
                        break;
                    case "移除势力战掉线":
                        if (World.势力战掉线玩家 != null && World.势力战掉线玩家.ContainsKey(array[1]))
                        {
                            World.势力战掉线玩家.Remove(array[1]);
                        }
                        break;
                    case "门派":
                        try
                        {
                            World.发送帮派消息(array[2], array[3], array[1], int.Parse(array[5]));
                        }
                        catch (Exception ex8)
                        {
                            Form1.WriteLine(1, "发送帮派消息出错：" + @string + ex8.Message);
                        }
                        break;
                    case "传音":
                        try
                        {
                            World.发送传音消息(int.Parse(array[1]), array[2], array[3], array[4]);
                        }
                        catch (Exception ex7)
                        {
                            Form1.WriteLine(1, "发送传音消息出错：" + @string + ex7.Message);
                        }
                        break;
                    case "传音返回":
                        try
                        {
                            World.发送传音返回消息(array[1], array[2], array[3]);
                        }
                        catch (Exception ex6)
                        {
                            Form1.WriteLine(1, "发送传音返回消息出错：" + @string + ex6.Message);
                        }
                        break;
                    case "更新副服务器端口":
                        try//这里是更新其他GS上线连接LS后更新了端口
                        {
                            World.银币服务器PORT = array[2];
                            Form1.WriteLine(1, @string);
                        }
                        catch (Exception ex5)
                        {
                            Form1.WriteLine(1, "更新副服务器端口：" + @string + ex5.Message);
                        }
                        break;
                    case "更新主服务器端口":
                        try//这里是更新其他GS上线连接LS后更新了端口
                        {
                            string[] array2 = array[1].Split(',');
                            if (array2.Length > 1)
                            {
                                foreach (ServerClass server in World.ServerList)
                                {
                                    if (server.ServerId == int.Parse(array2[0]))
                                    {
                                        server.SERVER_PORT = array2[1];
                                        break;
                                    }
                                }
                                Form1.WriteLine(1, @string);
                            }
                        }
                        catch (Exception ex4)
                        {
                            Form1.WriteLine(1, @string + ex4.Message);
                        }
                        break;
                    case "势力战进程":
                        try
                        {
                            World.势力战进程 = int.Parse(array[1]);
                            //World.势力战时间 = int.Parse(array[2]);
                            //World.势力战要求转职状态 = int.Parse(array[3]);
                        }
                        catch (Exception ex3)
                        {
                            Form1.WriteLine(1, @string + "|" + ex3.Message);
                        }
                        break;
                    case "势力战公告":
                        发送公告(int.Parse(array[1]), array[3]);
                        break;
                    case "狮吼功":
                        try
                        {
                            World.系统全局提示(array[1], array[2], 21);
                        }
                        catch (Exception ex2)
                        {
                            Form1.WriteLine(1, "发送狮吼功消息出错：" + @string + ex2.Message);
                        }
                        break;
                    case "装逼":
                        try
                        {
                            World.装逼全局提示(array[1], array[2], 21);
                        }
                        catch (Exception ex)
                        {
                            Form1.WriteLine(1, "发送装逼消息出错：" + @string + ex.Message);
                        }
                        break;
                    case "掉落全线提示":
                        {
                            if (array[1] == "OK")
                            {
                                World.系统全局提示(array[3], array[2], 23);
                            }
                        }
                        break;
                    case "强化全线提示":
                        {
                            if (array[1] == "OK")
                            {
                                World.系统全局提示(array[3], array[2], 20);
                            }
                        }
                        break;
                    case "门派杀人提示":
                        {
                            if (array[1] == "OK")
                            {
                                World.系统全局提示(array[3], array[2], 3);
                            }
                        }
                        break;
                    case "查人物":
                        {
                            Players players3 = World.检查玩家世界ID(int.Parse(array[1]));
                            if (players3 != null && array[2].Length > 0)
                            {
                                string[] array2 = array[2].Split(';');
                                string[] array3 = array2;
                                foreach (string text in array3)
                                {
                                    if (text.Length > 0 && !players3.在线帮派成员.Contains(text))
                                    {
                                        players3.在线帮派成员.Add(text);
                                    }
                                }
                            }
                            break;
                        }
                    case "狮子吼":
                        {
                            NetState value;
                            if (array[1] == "OK")
                            {
                                World.发送全服狮子吼消息广播数据(int.Parse(array[2]), array[3], int.Parse(array[4]), array[5], int.Parse(array[6]), int.Parse(array[7]));
                            }
                            else if (World.list.TryGetValue(int.Parse(array[2]), out value))
                            {
                                value.Player.系统提示("狮子吼列队以满请等待.....", 9, "系统提示");
                            }
                            break;
                        }
                    case "更新配置":
                        更新配置(array[1], array[2]);
                        break;
                }
            }
            catch (Exception ex9)
            {
                Form1.WriteLine(1, "验证服务器接收出错：" + @string + ex9.Message);
            }
        }

        public void 用户登陆(int serverid, string userid, string txt, string conip, string connip, string conmac)
        {
            try
            {
                NetState value;
                if (World.list.TryGetValue(serverid, out value))
                {
                    value.Player.连接登陆2(userid, txt, conip, connip, conmac);
                }
            }
            catch (Exception ex)
            {
                Form1.WriteLine(1, "验证服务器用户登陆出错：" + ex.Message);
            }
        }

        public void 用户换线登陆(int serverid, string userid, string 服务器ID, string 人物序号, string WorldID, string 选定类型, string 换线配置, string 绑定帐号)
        {
            try
            {
                NetState value;
                if (World.list.TryGetValue(serverid, out value))
                {
                    Players players = World.检查玩家(userid);
                    if (players == null)
                    {
                        value.Player.换线账号登陆(userid, 服务器ID, int.Parse(人物序号), int.Parse(WorldID), 选定类型, 换线配置, 绑定帐号);
                    }
                }
            }
            catch (Exception ex)
            {
                Form1.WriteLine(1, "验证用户换线登陆：" + ex.Message);
            }
        }

        public void 发送公告(int ggid, string txt)
        {
            try
            {
                foreach (Players value in World.allConnectedChars.Values)
                {
                    if (value != null)
                    {
                        switch (ggid)
                        {
                            case 0:
                                value.系统公告(txt);
                                break;
                            case 1:
                                value.系统滚动公告(txt);
                                break;
                            case 2:
                                value.系统提示(txt, 10, "系统信息");
                                break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Form1.WriteLine(1, "发送公告出错：" + ex.Message);
            }
        }

        public void 更新配置(string userid, string date)
        {
            Players players = World.检查玩家(userid);
            if (players != null)
            {
                if (players.快捷栏.Contains(1008000044))
                {
                    players.人物追加最大_HP += 300;
                }
                if (players.快捷栏.Contains(1008000045))
                {
                    players.人物追加最大_MP += 200;
                }
                if (!players.是否更新配置)
                {
                    byte[] array = Converter.hexStringToByte(date);
                    Buffer.BlockCopy(BitConverter.GetBytes(players.人物全服ID), 0, array, 5, 2);
                    players.换线更新配置(array, array.Length);
                }
                players.客户端设置 = date;
                players.更新HP_MP_SP();
            }
        }
        public void 用户踢出ID(string userid)
        {
            try
            {
                Players players = World.检查玩家(userid);
                string empty = string.Empty;
                string empty2 = string.Empty;
                string empty3 = string.Empty;

                if (players != null)
                {
                    string userid2 = players.Userid;
                    string userName = players.UserName;
                    if (players.Client.挂机)
                    {
                        players.Client.DisposedOffline();
                    }
                    else
                    {

                        players.Logout();
                        players.Client.Dispose();
                        World.conn.发送("踢出玩家ID|" + World.服务器ID + "|" + userid);
                        Form1.WriteLine(3, "玩家重复登陆 - 用户踢出ID [" + players.Userid + "]-[" + players.UserName + "]" + players.Client.ToString());
                    }
                }
            }
            catch (Exception ex)
            {
                Form1.WriteLine(1, "验证服务器用户踢出出错：" + userid + " " + ex.Message);
            }
        }
        public static void 用户踢出(int WorldID, string UserID)
        {
            try
            {
                Players players = World.检查玩家世界ID(WorldID);
                if (players == null)
                {
                    players = World.检查玩家(UserID);
                    if (players == null)
                    {
                        NetState netState;
                        if (World.list.TryGetValue(WorldID, out netState))
                        {
                            netState.delWorldIdd(WorldID);
                            netState.Player.OpClient(1);
                            netState.Dispose();
                        }
                        return;
                    }
                }
                players.OpClient(1);
                players.Client.Dispose();
                Form1.WriteLine(3, "用户踢出 [" + WorldID + "]");
            }
            catch (Exception ex)
            {
                Form1.WriteLine(1, string.Concat(new object[]
                {
            "验证服务器用户踢出出错：",
            WorldID,
            " ",
            ex.Message
                }));
            }
        }

    }

}
